# coding: utf-8
"""
@File  : depagenation.py
@Author: dc zhao
@Date  : 2021/03/24 morning 10:30
@description:
    Pagination class determine the structure of the output that could be used for pagination responses.
"""
from collections import OrderedDict
from fastapi.responses import JSONResponse


class PageNumberPagination(object):
    """
    A simple page number based style that supports page numbers as
    query parameters. For example:

    http://api.example.org/accounts/?page=4
    http://api.example.org/accounts/?page=4&page_size=100
    """
    default_page_size = 12

    # Client can control the page using this query parameter.

    # Client can control the page size using this query parameter.
    # Default is 'None'. Set to eg 'page_size' to enable usage.
    page_size_query_param = None

    # Set to an integer to limit the maximum page size the client may request.
    # Only relevant if 'page_size_query_param' has also been set.
    max_page_size = None

    def __init__(self, page_size=None, count=None, request=None, page=None):
        self.page_size = page_size if page_size else self.default_page_size
        self.count = count
        self.request = request
        self.page = page if page > 0 else 1

    def get_pages(self):
        return self.count//self.page_size + 1

    def has_next(self):
        return self.page < self.get_pages()

    def has_previous(self):
        return self.page > 1

    def previous_page_number(self):
        return self.page - 1

    def next_page_number(self):
        return self.page + 1

    def build_absolute_uri(self):
        return str(self.request.url)

    def get_query_params(self):
        return str(self.request.query_params)

    def replace_query_param(self, page_number):
        url = self.build_absolute_uri()
        query_params = self.get_query_params()
        replace_params = "page={}".format(page_number)
        return url.replace(query_params, replace_params)

    def get_next_link(self):
        if not self.has_next():
            return None
        page_number = self.next_page_number()
        url = self.replace_query_param(page_number)
        return url

    def get_previous_link(self):
        if not self.has_previous():
            return None
        page_number = self.previous_page_number()
        return self.replace_query_param(page_number)

    def get_paginated_response(self, data):
        return JSONResponse(OrderedDict([
            ("code", 200),
            ("msg", "success"),
            ('count', self.count),
            ("pages", self.get_pages()),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('results', data)
        ]))
